package view
{
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.utils.getDefinitionByName;
    import flash.utils.getTimer;

import constants.DialogType;

import constants.DialogType;

import constants.DialogType;

import constants.DialogType;

import mx.events.RSLEvent;
    import mx.preloaders.SparkDownloadProgressBar;
    
    public class AppPreloader extends SparkDownloadProgressBar
    {
        //----------------------------------------------------------------------
        //
        //  Override progress bar interface
        //
        //----------------------------------------------------------------------
        
        /**
         *  Event listener for the <code>FlexEvent.INIT_COMPLETE</code> event. This
         *  event mark end of framework initialization. In this point begining
         *  appliation initialize procces.
         *
         *  For MVC architectrue is ApplicationFacade created here. And run STARTUP command. Each
         *  command report it status to <code>completeCallback()<code> function on preloader for
         *  display one loading progress for all stages.
         *
         *  NOTE: This event can be commented out to stop preloader from completing during testing
         */
        override protected function initCompleteHandler(event:Event):void
        {
            initProgressCount = initProgressTotal;

            var appFacadeClass:Class = getDefinitionByName("AppFacade") as Class;
            var facade:* = appFacadeClass["getInstance"]();
            facade["startup"](this);
            sendCompleteEvent();
        }
        
        /**
         *  Creates the sub components of the display loading and initialazing progress.
         */
        override protected function createChildren():void
        {    
            updateDialog(showingDisplay);
        }
        
        /**
         * Event listener for the <code>RSLEvent.RSL_PROGRESS</code> event. 
         */
        override protected function rslProgressHandler(event:RSLEvent):void
        {
            updateDialog(showingDisplay);

            if (event.rslIndex && event.rslTotal) 
            {
                _rslIndex = event.rslIndex;
                _rslTotal = event.rslTotal;
            }
        }

        /**
         *  Event listener for the <code>FlexEvent.INIT_PROGRESS</code> event. 
         *  This implementation updates the progress bar
         *  each time the event is dispatched. 
         */
        override protected function initProgressHandler(event:Event):void
        {
            updateDialog(showingDisplay);

            initProgressCount++;
            if (initProgressCount > initProgressTotal)
                return;
            
            setInitProgress(initProgressCount, initProgressTotal);
        }
        
        /** 
         *  indicate download progress.
         */
        override protected function setDownloadProgress(completed:Number, total:Number):void 
        {
            loadingProgress = (completed * (_rslIndex + 1)) / (total * _rslTotal);
            updateProgress();
        }
        
        /** 
         *  Updates the inner portion of the download progress bar to
         *  indicate initialization progress.
         */
        override protected function setInitProgress(completed:Number, total:Number):void 
        {
            loadingProgress = 1.0;
            initializeProgress = (completed + appProgressCount) / (total + appProgressTotal);
            updateProgress();
        }

        private var loadingProgress:Number = 0.0;
        private var initializeProgress:Number = 0.0;




        //---------------------------------------------------------------------
        //
        //  Callbacks for application facade
        //
        //---------------------------------------------------------------------


        private var signin:Function = null;

        private var signup:Function = null;

        /**
         *  Application loading process handler
         *
         *  @param loadingStatusCode is additional information about loading
         *  progress.
         */
        public function completeCallback(loadingStatusCode:uint):void
        {
            appProgressCount++;

            setInitProgress(initProgressCount, initProgressTotal);
            sendCompleteEvent();
        }

        public function setPreloaderString(message:String):void
        {
            if (_dialog && "loadingText" in _dialog)
                _dialog["loadingText"] = message;
        }
        
        //----------------------------------------------------------------------
        //
        //  Private
        //
        //----------------------------------------------------------------------

        private var _startTime:int;
        
        private var _rslTotal:int = 10;
        private var _rslIndex:int = 1;

        /**
         *  Done flex's initialize stages count
         */
        private var initProgressCount:uint = 0;

        /**
         *  Done application's initialize stages count. This count can't be
         *  batter then appProgressTotal
         */
        private var appProgressCount:uint = 0;

        /**
         *  Total number of application initialize stages.
         */
        private var appProgressTotal:uint = 3;

        /**
         *  UI Component which display loading progress.
         */
        private var _dialog:DisplayObject;

        /**
         *  Current loading display.
         */
        private var showingDisplay:String = DialogType.LOADING;


        /**
         * Update displayed dialog and it position
         * @param type is DialogType constant
         */
        private function updateDialog(type:String):void
        {
            // Unavailabel type value
            if (type == null || type == "")
                return;

            // Center dialog
            if (_dialog)
            {
                _dialog.x = Math.round((stageWidth - _dialog.width) / 2);
                _dialog.y = Math.round((stageHeight - _dialog.height) / 2) - 200;
            }

            // exit form function if dialog already displayed
            if (showingDisplay == type && _dialog && contains(_dialog))
                return;

            showingDisplay = type;

            if (_dialog)
                removeChild(_dialog);

            // Create apropriate dialog
            switch (showingDisplay)
            {
                case DialogType.LOADING:
                    _dialog = new PreloaderDisplay();
                    break;

                case DialogType.SIGNIN:
                    appProgressTotal += 1;
                    _dialog = new SigninDialog();
                    _dialog.addEventListener("signinComplete", dialog_signinCompleteHandler)
                    break;

                case DialogType.SIGNUP:
                    appProgressTotal += 1;
                    _dialog = new SignupDialog();
                    _dialog.addEventListener("signupComplete", dialog_signupCompleteHandler);
                    break;

                case DialogType.TOOLTIP:
                    //TODO: add UIComponent for tips
                    break;

                default:
                    throw new Error("Preloader display try show unavailable dialog with name " + type);
                    break;
            }

            _dialog.x = Math.round((stageWidth - _dialog.width) / 2);
            _dialog.y = Math.round((stageHeight - _dialog.height) / 2) - 200;

            addChild(_dialog);
        }

        /**
         *  Complete event dispatched when all loading and initializing stages
         *  complete.
         */
        private function sendCompleteEvent():void
        {
            if (initProgressCount == initProgressTotal
                && appProgressCount == appProgressTotal)
            {
                dispatchEvent(new Event(Event.COMPLETE));
            }
        }

        /**
         *
         * @param isLoadingProgress
         */
        private function updateProgress():void
        {
            var percent:Number = loadingProgress * 0.5 + initializeProgress * 0.5;

            if (_dialog && "progress" in _dialog)
                _dialog["progress"] = percent;

            var displayPercent:String = Math.round(percent * 100).toString() + "%";
            var loadingText:String = (initializeProgress == 0.0 ? "Loading " : "Initializing ") + displayPercent;
            setPreloaderString(loadingText);
        }


        //---------------------------------------------------------------------
        //  Event handlers
        //---------------------------------------------------------------------

        private function dialog_signupCompleteHandler(event:Event):void
        {
            signup(_dialog["username"], _dialog["email"], _dialog["password"], _dialog["currency"], _dialog["balance"]);
        }

        private function dialog_signinCompleteHandler(event:Event):void
        {
            signin(_dialog["username"], _dialog["password"]);
        }
    }
}